package com.senlingspace.payment.douyin.bean.request;

import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.senlingspace.payment.douyin.DouyinFunctionEnum;
import com.senlingspace.payment.douyin.bean.response.DouyinProductResponse;
import lombok.Data;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * 创建商品、更新商品
 *
 * @author lebronjames
 * @date 2024/07/22
 */
@Data
public class DouyinProductRequest implements DouyinRequest<DouyinProductResponse> {

    /**
     * 商家 ID，传入时服务商须与该商家满足授权关系
     */
    @JsonProperty("account_id")
    private String accountId;

    /**
     * 商品
     */
    @JsonProperty("product")
    private Product product;

    /**
     * 售卖单元
     */
    @JsonProperty("sku")
    private SkuStruct sku;

    @Data
    public static class Product implements Serializable {

        /**
         * 商品 ID，创建时不必填写，更新时如有 out_id 可不填写
         */
        @JsonProperty("product_id")
        private String productId;

        /**
         * 外部商品 ID
         */
        @JsonProperty("out_id")
        private String outId;

        /**
         * 创建预定商品（product_type=13）时，传入关联的 SPU ID，由创建票种接口返回；
         * 创建预售券（product_type=12）时不传；
         */
        // @JsonProperty("spu_id")
        // private String spuId;

        /**
         * 商品名
         */
        @JsonProperty("product_name")
        private String productName;

        /**
         * 品类全名，保存时不必填写
         */
        @JsonProperty("category_full_name")
        private String categoryFullName;

        /**
         * 三级品类id
         */
        @JsonProperty("category_id")
        private Long categoryId;

        /**
         * 团购类型：（更新商品时不可修改）
         * 1：团购套餐
         * 4：日历房
         * 5：门票
         * 7：旅行跟拍
         * 8：一日游
         * 11：代金券
         * 12：新预售
         * 13：预定商品
         * 15：次卡
         */
        @JsonProperty("product_type")
        private Integer productType;

        /**
         * 商品二级类型(仅小程序酒旅填写)：1201（旅行社预售）
         * (ps：需product_type=12) (更新时不可修改)
         */
        @JsonProperty("product_sub_type")
        private Integer productSubType;

        /**
         * 业务线。（更新商品时不可修改）
         * 1：闭环自研开发者（如酒旅预售券）
         * 5：小程序
         */
        @JsonProperty("biz_line")
        private Integer bizLine;

        /**
         * 商家名
         */
        @JsonProperty("account_name")
        private String accountName;

        /**
         * 售卖开始时间(团购商品必填）时间戳（如 1729237730L）
         */
        @JsonProperty("sold_start_time")
        private Long soldStartTime;

        /**
         * 售卖结束时间(团购商品必填）(到期自动下架) 时间戳（如 1729237730L）
         */
        @JsonProperty("sold_end_time")
        private Long soldEndTime;

        /**
         * 第三方跳转链接，小程序商品必填
         */
        @JsonProperty("out_url")
        private String outUrl;

        /**
         * 店铺列表
         */
        @JsonProperty("pois")
        private List<Poi> pois;

        /**
         * 商品属性 KV，填写时参考商品发布和查询能力。填写时查询“查询商品模板”接口，map的value中数据最后要改成json串
         */
        @JsonProperty("attr_key_value_map")
        private Map<String, String> attrKeyValueMap;

        /**
         * 商品额外信息
         */
        @JsonProperty("product_ext")
        private ProductExt productExt;

    }

    @Data
    public static class Poi implements Serializable {
        /**
         * poiID，技术服务商保存商品填写该字段(在来客的门店管理列表中)
         */
        @JsonProperty("poi_id")
        private String poiId;

        /**
         * 接入方店铺id， 代运营服务商保存商品选择poi_id或者supplier_ext_id其中一个字段填写
         */
        @JsonProperty("supplier_ext_id")
        private String supplierExtId;

    }

    /**
     * 商品额外信息
     *
     * @author lebronjames
     * @date 2024/07/23
     */
    @Data
    public static class ProductExt implements Serializable {

        /**
         * true / null - 审核通过自动上架
         * false - 审核通过不自动上架
         */
        @JsonProperty("auto_online")
        private Boolean autoOnline;

        /**
         * 测试商品信息
         */
        @JsonProperty("test_extra")
        private TestExtra testExtra;

    }

    /**
     * 测试商品信息
     *
     * @author lebronjames
     * @date 2024/07/23
     */
    @Data
    public static class TestExtra implements Serializable {

        /**
         * 商品可见的用户UID列表，["123456"]，最多10个
         */
        @JsonProperty("uids")
        private List<String> uids;

        /**
         * 标记商品是否为测试商品，当test_flag=true时，
         * 1、uids数量需要大于0
         * 2、小程序商品必须传trade_url
         * 3、库存数不能大于50
         * 若要取消测试标记：须指定test_flag=false
         */
        @JsonProperty("test_flag")
        private Boolean testFlag;

    }

    /**
     * 售卖单元
     *
     * @author lebronjames
     * @date 2024/07/23
     */
    @Data
    public static class SkuStruct implements Serializable {

        /**
         * SKU ID，创建时不必填写
         */
        @JsonProperty("sku_id")
        private String skuId;

        /**
         * SKU名称
         */
        @JsonProperty("sku_name")
        private String skuName;

        /**
         * 原价，团购创建时如有 commodity 属性可不填，会根据菜品搭配计算原价，单位分。
         * 计算方式： 菜品搭配x选n，菜品组价格从大到小排序，累加n个菜品组价格得出原价
         */
        @JsonProperty("origin_amount")
        private Integer originAmount;

        /**
         * 实际支付价格，单位分（注：创建预售商品为必传，创建预定商品时非必传）
         */
        @JsonProperty("actual_amount")
        private Integer actualAmount;

        /**
         * sku属性KV，填写时参考下文「attr_key_value_map的格式」
         */
        @JsonProperty("attr_key_value_map")
        private Map<String, String> attrKeyValueMap;

        /**
         * 状态，1 为在线 ； 默认传1
         */
        @JsonProperty("status")
        private Integer status;

        /**
         * 库存信息
         */
        @JsonProperty("stock")
        private StockStruct stock;

        /**
         * 第三方 ID
         */
        @JsonProperty("bind_skus")
        private List<String> bindSkus;

    }

    @Data
    public static class StockStruct implements Serializable {

        /**
         * 库存上限类型。
         * 1：有限库存
         * 2：无限库存，2 时 stock_qty和avail_qty 字段无意义
         */
        @JsonProperty("limit_type")
        private Integer limitType;

        /**
         * 总库存，limit_type=2 时无意义
         */
        @JsonProperty("stock_qty")
        private Integer stockQty;

    }

    @Override
    public DouyinFunctionEnum getFunction() {
        return DouyinFunctionEnum.product_save_or_update;
    }

    @Override
    public String getBody() {
        DouyinProductRequest request = new DouyinProductRequest();
        request.setAccountId(this.accountId);

        Product pdt = new Product();
        pdt.setProductId(this.product.productId);
        pdt.setOutId(this.product.outId);
        pdt.setProductName(this.product.productName);
        pdt.setCategoryFullName(this.product.categoryFullName);
        pdt.setCategoryId(this.product.categoryId);
        pdt.setProductType(1);
        pdt.setProductSubType(null);
        pdt.setBizLine(1);
        pdt.setAccountName(this.product.accountName);
        pdt.setSoldStartTime(this.product.soldStartTime);
        pdt.setSoldEndTime(this.product.soldEndTime);
        pdt.setOutUrl(null);
        pdt.setPois(this.product.pois);
        pdt.setAttrKeyValueMap(this.product.attrKeyValueMap);
        pdt.setProductExt(this.product.productExt);
        request.setProduct(product);

        SkuStruct struct = new SkuStruct();
        struct.setSkuId(this.sku.skuId);
        struct.setSkuName(this.sku.skuName);
        struct.setOriginAmount(this.sku.originAmount);
        struct.setActualAmount(this.sku.actualAmount);
        struct.setAttrKeyValueMap(this.sku.attrKeyValueMap);
        struct.setStatus(1);
        struct.setStock(this.sku.stock);
        struct.setBindSkus(null);
        request.setSku(struct);

        return JSON.toJSONString(request);
    }

    @Override
    public Class<DouyinProductResponse> getResponseType() {
        return DouyinProductResponse.class;
    }

}
